package com.zzyl.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.json.JSONUtil;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.LoginDto;
import com.zzyl.entity.User;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.UserMapper;
import com.zzyl.properties.SecurityConfigProperties;
import com.zzyl.service.UserService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

   @Value("${zzyl.framework.jwt.base64-encoded-secret-key}")
   private String secretKey;

    @Value("${zzyl.framework.jwt.ttl}")
    private Integer ttl;

    @Autowired
    private SecurityConfigProperties securityConfigProperties;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    /**
     * 后台用户登录
     *
     * @param loginDto
     * @return
     */
    @Override
    public UserVo login(LoginDto loginDto) {
        //1. 校验参数是否为空
        if(ObjectUtil.isEmpty(loginDto)
                || ObjectUtil.isEmpty(loginDto.getUsername())
                || ObjectUtil.isEmpty(loginDto.getPassword())){
            throw new BaseException(BasicEnum.LOGIN_DATA_NOT_NULL);
        }

        //2. 根据用户名查询用户
        User user = userMapper.selectByName(loginDto.getUsername());

        //3. 判断用户是否为空
        if(ObjectUtil.isEmpty(user)){
            throw new BaseException(BasicEnum.LOGIN_LOSE_EFFICACY);
        }

        //4. 判断用户的状态是否为禁用
        if(SuperConstant.DATA_STATE_1.equals(user.getDataState())){
            throw new BaseException(BasicEnum.LOGIN_STATA_DEIABLED);
        }

        //5. 校验密码(明文和密文)
        boolean flag = BCrypt.checkpw(loginDto.getPassword(), user.getPassword());
        if(!flag){
            throw new BaseException(BasicEnum.LOGIN_USERNAME_PWD_ERROR);
        }

        //6. 生成token
        UserVo vo = new UserVo();
        BeanUtils.copyProperties(user,vo);

        //脱敏处理-处理掉敏感数据
        vo.setPassword("");
        Map<String,Object> data = new HashMap<>();
        vo.setUpdateTime(null);
        vo.setCreateTime(null);
        data.put("currentUser", vo);

        String token = JwtUtil.createJWT(secretKey, ttl, data);
        vo.setUserToken(token);

        //7.查询当前用户的所有能访问的资源， 然后注入白名单数据并合并2个数据 然后存储到redis
        List<String> pathUrls = userMapper.selectPathById(vo.getId());
        Collections.addAll(pathUrls, securityConfigProperties.getPublicAccessUrls().toArray(new String[0]));

        redisTemplate.opsForValue().set(SuperConstant.USER_RESOURCE_ + vo.getId(), JSONUtil.toJsonStr(pathUrls));

        //8. 构建返回结果并返回
        return vo;
    }
}
